package com.simple.core.spec;

import org.springframework.lang.Nullable;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaDelete;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.io.Serializable;

/**
 * @author FanXing
 * @date 2023年03月04日 18:31
 */
public interface DeleteSpec<T> extends Serializable {

    long serialVersionUID = 1L;

    static <T> DeleteSpec<T> not(@Nullable DeleteSpec<T> spec) {

        return spec == null //
                ? (root, query, builder) -> null //
                : (root, query, builder) -> builder.not(spec.toPredicate(root, query, builder));
    }

    static <T> DeleteSpec<T> where(@Nullable DeleteSpec<T> spec) {
        return spec == null ? (root, query, builder) -> null : spec;
    }

    default DeleteSpec<T> and(@Nullable DeleteSpec<T> other) {
        return DeleteSpecComposition.composed(this, other, CriteriaBuilder::and);
    }

    default DeleteSpec<T> or(@Nullable DeleteSpec<T> other) {
        return DeleteSpecComposition.composed(this, other, CriteriaBuilder::or);
    }

    @Nullable
    Predicate toPredicate(Root<T> root, CriteriaDelete<?> criteriaDelete, CriteriaBuilder criteriaBuilder);
}
